home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / shells / bashsrc.zoo / nojobs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-05  |  6.7 KB  |  302 lines

  1. /* The thing that makes children, remembers them, and contains wait loops. */
  2. /* this will probably only work with System V */
  3.  
  4. /* Copyright (C) 1987,1989 Free Software Foundation, Inc.
  5.  
  6. This file is part of GNU Bash, the Bourne Again SHell.
  7.  
  8. Bash is free software; you can redistribute it and/or modify it under
  9. the terms of the GNU General Public License as published by the Free
  10. Software Foundation; either version 1, or (at your option) any later
  11. version.
  12.  
  13. Bash is distributed in the hope that it will be useful, but WITHOUT ANY
  14. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16. for more details.
  17.  
  18. You should have received a copy of the GNU General Public License along
  19. with Bash; see the file COPYING.  If not, write to the Free Software
  20. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  21.  
  22. #include <stdio.h>
  23. #include <sys/types.h>
  24. #include <sys/ttold.h>
  25. #include <fcntl.h>
  26. #include <termio.h>
  27. #include <signal.h>
  28. #include <setjmp.h>
  29. #include <errno.h>
  30.  
  31. #include "config.h"
  32. #include "general.h"
  33. #include "jobs.h"
  34.  
  35. #ifndef SIGABRT
  36. #define SIGABRT SIGIOT
  37. #endif
  38.  
  39. #ifdef SYSV
  40. #define killpg(pg, sig)        kill(-(pg),(sig))
  41. #endif /* SYSV */
  42.  
  43. #if defined(SYSV) || defined(HPUX)
  44. int siginterrupt (sig, flag) int sig, flag; { return 0; }
  45. #endif
  46.  
  47. int last_made_pid = -1;
  48. int last_asynchronous_pid = -1;
  49.  
  50. /*
  51.  * Initialize the job control mechanism, and set up the tty stuff.
  52.  */
  53. initialize_jobs ()
  54. {
  55. }
  56.  
  57. /*
  58.  * Setup this shell to handle C-C, etc.
  59.  */
  60. initialize_job_signals ()
  61. {
  62.   extern int login_shell;
  63.   extern sighandler throw_to_top_level ();
  64.  
  65.   signal (SIGINT, throw_to_top_level);
  66.   signal (SIGQUIT, SIG_IGN);
  67.  
  68.   /* If this is a login shell we don't wish to be disturbed by
  69.      stop signals. */
  70.   if (login_shell)
  71.     {
  72. #ifdef SIGSTOP
  73.       signal (SIGSTOP, SIG_IGN);
  74. #endif
  75. #ifdef SIGTSTP
  76.       signal (SIGTSTP, SIG_IGN);
  77.       signal (SIGTTOU, SIG_IGN);
  78.       signal (SIGTTIN, SIG_IGN);
  79. #endif
  80.     }
  81. }
  82.  
  83. /*
  84.  * Fork, handling errors.  Returns the pid of the newly made child, or 0.
  85.  * COMMAND is just for remembering the name of the command; we don't do
  86.  * anything else with it.  ASYNC_P says what to do with the tty.  If
  87.  * non-zero, then don't give it away.
  88.  */
  89. int
  90. make_child (command, async_p)
  91.      char *command;
  92.      int async_p;
  93. {
  94.   int pid;
  95.  
  96.   /* Discard saved memory. */
  97.   if (command)  
  98.     free (command);
  99.  
  100.   /* Make new environment array if neccessary. */
  101.   maybe_make_export_env ();
  102.  
  103.   /* Create the child, handle severe errors. */
  104.   if ((pid = fork ()) < 0)
  105.     {
  106.       report_error ("Memory exhausted or process overflow!");
  107.       throw_to_top_level ();
  108.     }
  109.  
  110.   if (!pid)
  111.     {
  112.       /*
  113.        * Ignore INT and QUIT in asynchronous children.
  114.        */
  115.       if (async_p)
  116.     {
  117.       signal (SIGINT, SIG_IGN);
  118.       signal (SIGQUIT, SIG_IGN);
  119.       last_asynchronous_pid = getpid ();
  120.     }
  121.       else
  122.     {
  123.       signal (SIGINT, SIG_DFL);
  124.       signal (SIGQUIT, SIG_DFL);
  125.     }
  126.  
  127.       /* Children are easily terminated with SIGTERM. */
  128.       signal (SIGTERM, SIG_DFL);
  129.  
  130.       /* Set the resource limits for this child. (In ulimit.c). */
  131.       set_process_resource_limits ();
  132.     }
  133.   else
  134.     {
  135.       /*
  136.        * In the parent.
  137.        */
  138.       last_made_pid = pid;
  139.  
  140.       if (async_p)
  141.     last_asynchronous_pid = pid;
  142.     }
  143.   return (pid);
  144. }
  145.  
  146. /* Wait for a single pid (PID) and return its exit status. */
  147.  
  148. wait_for_single_pid (pid)
  149.      int pid;
  150. {
  151.   int got_pid;
  152.   union wait status;
  153.  
  154.   while ((got_pid = wait (&status)) != pid)
  155.     {
  156.       if (got_pid < 0)
  157.     {
  158.       if (errno != EINTR && errno != ECHILD)
  159.         file_error ("wait");
  160.       break;
  161.     }
  162.     }
  163.   QUIT;
  164. }
  165.  
  166. /* Wait for all of the shell's children to exit. */
  167.  
  168. wait_for_background_pids ()
  169. {
  170.   /* If we aren't using job control, we let the kernel take care of the
  171.      bookkeeping for us.  wait () will return -1 and set errno to ECHILD 
  172.      when there are no more unwaited-for child processes on both 4.2BSD-based
  173.      and System V-based systems. */
  174.  
  175.   while (1)
  176.     {
  177.       int got_pid;
  178.       union wait status;
  179.  
  180.       while ((got_pid = wait(&status)) != -1)  /* wait for ECHILD */
  181.     ;
  182.       if (errno != EINTR && errno != ECHILD)
  183.     file_error("wait");
  184.       break;
  185.     }
  186.  
  187.   QUIT;
  188. }
  189.  
  190. /*
  191.  * Wait for pid (one of our children) to terminate.
  192.  */
  193. int
  194. wait_for (pid)
  195.      int pid;
  196. {
  197.   extern int interactive;
  198.   int got_pid, return_val, oldmask;
  199.   union wait status;
  200.  
  201.   while ((got_pid = wait (&status)) != pid)
  202.     {
  203.       if (got_pid < 0 && errno == ECHILD)
  204.     {
  205.       status.w_termsig = status.w_retcode = 0;
  206.       break;
  207.     }
  208.       else if (got_pid < 0 && errno != EINTR)
  209.     programming_error ("got errno %d while waiting for %d", errno, pid);
  210.     }
  211.  
  212.   if (interactive)    /* allow the user to ^C out of the builtin wait */
  213.     QUIT;
  214.  
  215.   /* Default return value. */
  216.   return_val = status.w_retcode & 0x7f;
  217.  
  218.   if (status.w_termsig != 0 && status.w_termsig != WSTOPPED)
  219.     {
  220.       extern char *sys_siglist[];
  221.       fprintf (stderr, "%s", sys_siglist[status.w_termsig]);
  222.       if (status.w_coredump)
  223.     fprintf (stderr, " (core dumped)");
  224.       fprintf (stderr, "\n");
  225.       return_val = status.w_termsig + 128;
  226.     }
  227.  
  228.   if (status.w_termsig != 0)
  229.     set_tty_state ();
  230.   else
  231.     get_tty_state ();
  232.  
  233.   return (return_val);
  234. }
  235.  
  236. /* Give PID SIGNAL.  This determines what job the pid belongs to (if any).
  237.    If PID does belong to a job, and the job is stopped, then CONTinue the
  238.    job after giving it SIGNAL.  Returns -1 on failure.  If GROUP is non-null,
  239.    then kill the process group associated with PID. */
  240. int
  241. kill_pid (pid, signal, group)
  242.      int pid, signal, group;
  243. {
  244.   int result;
  245.  
  246.   if (group)
  247.     result = killpg (pid, signal);
  248.   else
  249.     result = kill (pid, signal);
  250.  
  251.   return (result);
  252. }
  253.  
  254. static struct termio shell_tty_info;
  255.  
  256. /* Fill the contents of shell_tty_info with the current tty info. */
  257. get_tty_state ()
  258. {
  259.   int tty = open ("/dev/tty", O_RDONLY);
  260.   if (tty != -1)
  261.     {
  262.       ioctl (tty, TCGETA, &shell_tty_info);
  263.       close (tty);
  264.     }
  265. }
  266.  
  267. /* Make the current tty use the state in shell_tty_info. */
  268. set_tty_state ()
  269. {
  270.   int tty = open ("/dev/tty", O_RDONLY);
  271.   if (tty != -1)
  272.     {
  273.       ioctl (tty, TCSETAW, &shell_tty_info);  /* Wait for output, no flush */
  274.       close (tty);
  275.     }
  276. }
  277.  
  278. /* Give the terminal to PGRP.  */
  279. give_terminal_to (pgrp)
  280.      int pgrp;
  281. {
  282. }
  283.  
  284. /*
  285.  * stop a pipeline
  286.  */
  287. stop_pipeline (async, ignore)
  288.      int async;
  289.      char *ignore;
  290. {
  291. }
  292.  
  293. /*
  294.  * Print descriptive information about the job with leader pid PID.
  295.  */
  296.  
  297. describe_pid (pid)
  298.      int pid;
  299. {
  300.   fprintf (stderr, "<%d>\n", pid);
  301. }
  302.